<?php
/**
 * Plugin Name: Wtk Seo Plugin
 * Plugin URI: https://example.com/comprehensive-wordpress-seo
 * Description: A plugin to add SEO meta titles and descriptions for all WordPress content types and dynamically generated pages.
 * Version: 1.3
 * Author: Wayne
 * Author URI: https://example.com
 * License: GPL v2 or later
 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
 */

if (!defined('ABSPATH')) {
    exit; // Exit if accessed directly
}

// Register Custom Post Type 'book'
function create_book_post_type() {
    $labels = array(
        'name'                  => _x( 'Books', 'Post Type General Name', 'textdomain' ),
        'singular_name'         => _x( 'Book', 'Post Type Singular Name', 'textdomain' ),
        'menu_name'             => __( 'Books', 'textdomain' ),
        'name_admin_bar'        => __( 'Book', 'textdomain' ),
        'archives'              => __( 'Book Archives', 'textdomain' ),
        'attributes'            => __( 'Book Attributes', 'textdomain' ),
        'parent_item_colon'     => __( 'Parent Book:', 'textdomain' ),
        'all_items'             => __( 'All Books', 'textdomain' ),
        'add_new_item'          => __( 'Add New Book', 'textdomain' ),
        'add_new'               => __( 'Add New', 'textdomain' ),
        'new_item'              => __( 'New Book', 'textdomain' ),
        'edit_item'             => __( 'Edit Book', 'textdomain' ),
        'update_item'           => __( 'Update Book', 'textdomain' ),
        'view_item'             => __( 'View Book', 'textdomain' ),
        'view_items'            => __( 'View Books', 'textdomain' ),
        'search_items'          => __( 'Search Book', 'textdomain' ),
        'not_found'             => __( 'Not found', 'textdomain' ),
        'not_found_in_trash'    => __( 'Not found in Trash', 'textdomain' ),
        'featured_image'        => __( 'Featured Image', 'textdomain' ),
        'set_featured_image'    => __( 'Set featured image', 'textdomain' ),
        'remove_featured_image' => __( 'Remove featured image', 'textdomain' ),
        'use_featured_image'    => __( 'Use as featured image', 'textdomain' ),
        'insert_into_item'      => __( 'Insert into book', 'textdomain' ),
        'uploaded_to_this_item' => __( 'Uploaded to this book', 'textdomain' ),
        'items_list'            => __( 'Books list', 'textdomain' ),
        'items_list_navigation' => __( 'Books list navigation', 'textdomain' ),
        'filter_items_list'     => __( 'Filter books list', 'textdomain' ),
    );
    $args = array(
        'label'                 => __( 'Book', 'textdomain' ),
        'description'           => __( 'A post type for books', 'textdomain' ),
        'labels'                => $labels,
        'supports'              => array( 'title', 'editor', 'thumbnail', 'excerpt', 'comments' ),
        'taxonomies'            => array( 'category', 'post_tag' ),
        'hierarchical'          => false,
        'public'                => true,
        'show_ui'               => true,
        'show_in_menu'          => true,
        'menu_position'         => 5,
        'show_in_admin_bar'     => true,
        'show_in_nav_menus'     => true,
        'can_export'            => true,
        'has_archive'           => true,
        'exclude_from_search'   => false,
        'publicly_queryable'    => true,
        'capability_type'       => 'post',
    );
    register_post_type( 'book', $args );
}
add_action( 'init', 'create_book_post_type', 0 );


// Register Custom Taxonomy 'genre'
function create_book_genre_taxonomy() {
    $labels = array(
        'name'                       => _x( 'Genres', 'Taxonomy General Name', 'textdomain' ),
        'singular_name'              => _x( 'Genre', 'Taxonomy Singular Name', 'textdomain' ),
        'menu_name'                  => __( 'Genres', 'textdomain' ),
        'all_items'                  => __( 'All Genres', 'textdomain' ),
        'parent_item'                => __( 'Parent Genre', 'textdomain' ),
        'parent_item_colon'          => __( 'Parent Genre:', 'textdomain' ),
        'new_item_name'              => __( 'New Genre Name', 'textdomain' ),
        'add_new_item'               => __( 'Add New Genre', 'textdomain' ),
        'edit_item'                  => __( 'Edit Genre', 'textdomain' ),
        'update_item'                => __( 'Update Genre', 'textdomain' ),
        'view_item'                  => __( 'View Genre', 'textdomain' ),
        'separate_items_with_commas' => __( 'Separate genres with commas', 'textdomain' ),
        'add_or_remove_items'        => __( 'Add or remove genres', 'textdomain' ),
        'choose_from_most_used'      => __( 'Choose from the most used', 'textdomain' ),
        'popular_items'              => __( 'Popular Genres', 'textdomain' ),
        'search_items'               => __( 'Search Genres', 'textdomain' ),
        'not_found'                  => __( 'Not Found', 'textdomain' ),
        'no_terms'                   => __( 'No genres', 'textdomain' ),
        'items_list'                 => __( 'Genres list', 'textdomain' ),
        'items_list_navigation'      => __( 'Genres list navigation', 'textdomain' ),
    );
    $args = array(
        'labels'                     => $labels,
        'hierarchical'               => true, // Set to false for non-hierarchical (tags)
        'public'                     => true,
        'show_ui'                    => true,
        'show_admin_column'          => true,
        'show_in_nav_menus'          => true,
        'show_tagcloud'              => true,
    );
    register_taxonomy( 'genre', array( 'book' ), $args );
}
add_action( 'init', 'create_book_genre_taxonomy', 0 );


class Wtk_Seo_Plugin {
    public function __construct() {
        // Hook into WordPress
        add_filter('pre_get_document_title', array($this, 'get_seo_title'), 999);
        add_action('wp_head', array($this, 'output_seo_meta_tags'), 1);
        add_action('admin_menu', array($this, 'add_admin_menu'));
        add_action('admin_init', array($this, 'register_settings'));
        
        // Add meta boxes for posts, pages, and custom post types
        add_action('add_meta_boxes', array($this, 'add_seo_meta_boxes'));
        add_action('save_post', array($this, 'save_seo_meta_data'));
        
        // Add fields to category, tag, and custom taxonomy edit forms
        add_action('category_edit_form_fields', array($this, 'add_taxonomy_seo_fields'), 10, 2);
        add_action('post_tag_edit_form_fields', array($this, 'add_taxonomy_seo_fields'), 10, 2);
        add_action('edit_term', array($this, 'save_taxonomy_seo_fields'), 10, 3);

        // Add support for custom post type archives
        add_action('admin_init', array($this, 'add_cpt_archive_seo_fields'));
    }

    public function output_seo_meta_tags() {
        $title = $this->get_seo_title();
        $description = $this->get_seo_description();

        if (!empty($title)) {
            echo "<meta property='og:title' content='" . esc_attr($title) . "'>\n";
        }

        if (!empty($description)) {
            echo "<meta name='description' content='" . esc_attr($description) . "'>\n";
            echo "<meta property='og:description' content='" . esc_attr($description) . "'>\n";
        }
    }

    public function get_seo_title($title = '') {
        global $post;

        if (is_singular()) {
            $custom_title = get_post_meta(get_the_ID(), '_seo_title', true);
            if (!empty($custom_title)) {
                return $custom_title;
            }
        } elseif (is_post_type_archive()) {
            $post_type = get_query_var('post_type');
            $custom_title = get_option("seo_{$post_type}_archive_title");
            if (!empty($custom_title)) {
                return $custom_title;
            }
        } elseif (is_category() || is_tag() || is_tax()) {
            $term = get_queried_object();
            $custom_title = get_term_meta($term->term_id, '_seo_title', true);
            if (!empty($custom_title)) {
                return $custom_title;
            }
        } elseif (is_home() || is_front_page()) {
            $custom_title = get_option('seo_home_title');
            if (!empty($custom_title)) {
                return $custom_title;
            }
        }

        // If we haven't returned a custom title, let WordPress handle it
        return $title;
    }

    public function get_seo_description() {
        global $post;

        if (is_singular()) {
            $description = get_post_meta(get_the_ID(), '_seo_description', true);
            if (!empty($description)) {
                return $description;
            }
            // Fall back to excerpt or trimmed content
            return $this->get_default_description($post);
        } elseif (is_post_type_archive()) {
            $post_type = get_query_var('post_type');
            $description = get_option("seo_{$post_type}_archive_description");
            if (!empty($description)) {
                return $description;
            }
            // Fall back to post type description
            $post_type_obj = get_post_type_object($post_type);
            return !empty($post_type_obj->description) ? wp_trim_words($post_type_obj->description, 30) : '';
        } elseif (is_category() || is_tag() || is_tax()) {
            $term = get_queried_object();
            $description = get_term_meta($term->term_id, '_seo_description', true);
            if (!empty($description)) {
                return $description;
            }
            // Fall back to term description
            return wp_trim_words(strip_tags($term->description), 30);
        } elseif (is_home() || is_front_page()) {
            $description = get_option('seo_home_description');
            if (!empty($description)) {
                return $description;
            }
            // Fall back to site description
            return get_bloginfo('description');
        }

        // For other pages, we'll use a generic description or return empty
        return '';
    }

    private function get_default_description($post) {
        $excerpt = get_the_excerpt($post);
        if (!empty($excerpt)) {
            return wp_trim_words($excerpt, 30);
        }
        return wp_trim_words(strip_tags($post->post_content), 30);
    }

    public function add_admin_menu() {
        add_options_page(
            'SEO Settings',
            'SEO Settings',
            'manage_options',
            'comprehensive-wordpress-seo',
            array($this, 'seo_settings_page')
        );
    }

    public function register_settings() {
        register_setting('comprehensive-wordpress-seo', 'seo_home_title');
        register_setting('comprehensive-wordpress-seo', 'seo_home_description');

        // Register settings for custom post type archives
        $post_types = get_post_types(array('public' => true, 'has_archive' => true), 'names');
        foreach ($post_types as $post_type) {
            register_setting('comprehensive-wordpress-seo', "seo_{$post_type}_archive_title");
            register_setting('comprehensive-wordpress-seo', "seo_{$post_type}_archive_description");
        }
    }

    public function seo_settings_page() {
        ?>
        <div class="wrap">
            <h1>SEO Settings</h1>
            <form method="post" action="options.php">
                <?php settings_fields('comprehensive-wordpress-seo'); ?>
                <?php do_settings_sections('comprehensive-wordpress-seo'); ?>
                <h2>Home Page SEO</h2>
                <table class="form-table">
                    <tr valign="top">
                        <th scope="row">Home Page Title</th>
                        <td><input type="text" name="seo_home_title" value="<?php echo esc_attr(get_option('seo_home_title')); ?>" /></td>
                    </tr>
                    <tr valign="top">
                        <th scope="row">Home Page Description</th>
                        <td><textarea name="seo_home_description" rows="3" cols="50"><?php echo esc_textarea(get_option('seo_home_description')); ?></textarea></td>
                    </tr>
                </table>

                <h2>Custom Post Type Archive SEO</h2>
                <?php
                $post_types = get_post_types(array('public' => true, 'has_archive' => true), 'objects');
                foreach ($post_types as $post_type) :
                ?>
                    <h3><?php echo esc_html($post_type->label); ?> Archive</h3>
                    <table class="form-table">
                        <tr valign="top">
                            <th scope="row"><?php echo esc_html($post_type->label); ?> Archive Title</th>
                            <td><input type="text" name="seo_<?php echo esc_attr($post_type->name); ?>_archive_title" value="<?php echo esc_attr(get_option("seo_{$post_type->name}_archive_title")); ?>" /></td>
                        </tr>
                        <tr valign="top">
                            <th scope="row"><?php echo esc_html($post_type->label); ?> Archive Description</th>
                            <td><textarea name="seo_<?php echo esc_attr($post_type->name); ?>_archive_description" rows="3" cols="50"><?php echo esc_textarea(get_option("seo_{$post_type->name}_archive_description")); ?></textarea></td>
                        </tr>
                    </table>
                <?php endforeach; ?>

                <?php submit_button(); ?>
            </form>
        </div>
        <?php
    }

    public function add_seo_meta_boxes() {
        $post_types = get_post_types(array('public' => true));
        foreach ($post_types as $post_type) {
            add_meta_box(
                'seo_meta_box',
                'SEO Settings',
                array($this, 'seo_meta_box_callback'),
                $post_type,
                'normal',
                'high'
            );
        }
    }

    public function seo_meta_box_callback($post) {
        wp_nonce_field('seo_meta_box', 'seo_meta_box_nonce');
        $seo_title = get_post_meta($post->ID, '_seo_title', true);
        $seo_description = get_post_meta($post->ID, '_seo_description', true);
        ?>
        <p>
            <label for="seo_title">SEO Title:</label>
            <input type="text" id="seo_title" name="seo_title" value="<?php echo esc_attr($seo_title); ?>" style="width: 100%;" />
        </p>
        <p>
            <label for="seo_description">SEO Description:</label>
            <textarea id="seo_description" name="seo_description" rows="3" style="width: 100%;"><?php echo esc_textarea($seo_description); ?></textarea>
        </p>
        <?php
    }

    public function save_seo_meta_data($post_id) {
        if (!isset($_POST['seo_meta_box_nonce']) || !wp_verify_nonce($_POST['seo_meta_box_nonce'], 'seo_meta_box')) {
            return;
        }

        if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
            return;
        }

        if (isset($_POST['seo_title'])) {
            update_post_meta($post_id, '_seo_title', sanitize_text_field($_POST['seo_title']));
        }

        if (isset($_POST['seo_description'])) {
            update_post_meta($post_id, '_seo_description', sanitize_textarea_field($_POST['seo_description']));
        }
    }

    public function add_taxonomy_seo_fields($term) {
        $seo_title = get_term_meta($term->term_id, '_seo_title', true);
        $seo_description = get_term_meta($term->term_id, '_seo_description', true);
        ?>
        <tr class="form-field">
            <th scope="row"><label for="seo_title">SEO Title</label></th>
            <td>
                <input type="text" name="seo_title" id="seo_title" value="<?php echo esc_attr($seo_title); ?>" />
                <p class="description">Enter a custom SEO title for this term.</p>
            </td>
        </tr>
        <tr class="form-field">
            <th scope="row"><label for="seo_description">SEO Description</label></th>
            <td>
                <textarea name="seo_description" id="seo_description" rows="5" cols="50"><?php echo esc_textarea($seo_description); ?></textarea>
                <p class="description">Enter a custom SEO description for this term.</p>
            </td>
        </tr>
        <?php
    }

    public function save_taxonomy_seo_fields($term_id) {
        if (isset($_POST['seo_title'])) {
            update_term_meta($term_id, '_seo_title', sanitize_text_field($_POST['seo_title']));
        }

        if (isset($_POST['seo_description'])) {
            update_term_meta($term_id, '_seo_description', sanitize_textarea_field($_POST['seo_description']));
        }
    }

    public function add_cpt_archive_seo_fields() {
        $post_types = get_post_types(array('public' => true, 'has_archive' => true), 'objects');
        foreach ($post_types as $post_type) {
            add_settings_section(
                "seo_{$post_type->name}_archive_section",
                "{$post_type->label} Archive SEO",
                null,
                'comprehensive-wordpress-seo'
            );

            add_settings_field(
                "seo_{$post_type->name}_archive_title",
                "{$post_type->label} Archive Title",
                array($this, 'render_cpt_archive_field'),
                'comprehensive-wordpress-seo',
                "seo_{$post_type->name}_archive_section",
                array('name' => "seo_{$post_type->name}_archive_title", 'type' => 'text')
            );

            add_settings_field(
                "seo_{$post_type->name}_archive_description",
                "{$post_type->label} Archive Description",
                array($this, 'render_cpt_archive_field'),
                'comprehensive-wordpress-seo',
                "seo_{$post_type->name}_archive_section",
                array('name' => "seo_{$post_type->name}_archive_description", 'type' => 'textarea')
            );
        }
    }

    public function render_cpt_archive_field($args) {
        $option = get_option($args['name']);
        if ($args['type'] === 'text') {
            echo "<input type='text' id='{$args['name']}' name='{$args['name']}' value='" . esc_attr($option) . "' />";
        } elseif ($args['type'] === 'textarea') {
            echo "<textarea id='{$args['name']}' name='{$args['name']}' rows='3' cols='50'>" . esc_textarea($option) . "</textarea>";
        }
    }
}

new Wtk_Seo_Plugin();